import re
from datetime import datetime
from enetity_extraction.Information_Extraction import extract_information
from enetity_extraction.company_data_test import get_data
from enetity_extraction.test_docx import get_docx_extraction_result


#出生日期校验
def is_valid_birthday(date_str):

    date_pattern = re.compile(r'^\d{4}年\d{1,2}月\d{1,2}日$')
    if not date_pattern.match(date_str):
        return "出生日期不合法"
    try:

        birthday =datetime.strptime(date_str, '%Y年%m月%d日')

        if birthday.year < 1900:
            return "出生年份不在合理范围内"

        if birthday > datetime.now():
            return "日期不能超过今天"

        return 1
    except ValueError:
        return "出生日期不合法"

#身份证号校验
def is_valid_date(date_str):
    if not re.match(r'^\d{8}$', date_str):
        return False
    try:
        birthday = datetime.strptime(date_str, '%Y%m%d')
        if birthday.year < 1900:
            return False
        if birthday > datetime.now():
            return False
        return True
    except ValueError:
        return False
def is_valid_address_number_all(address_number):
    # 打开文件并读取所有行
    with open('logic_rule/data/行政编码包含已撤销.txt', 'r', encoding='utf-8') as file:
        lines = file.readlines()
    # 去掉每行的换行符并存入数组
    lines = [line.strip() for line in lines]
    return address_number in lines
def is_valid_IDcard(IDcard):
    #GB11643－1999

    if len(IDcard) != 18:
        return "身份证长度错误"

    # 身份证前17位应为数字，最后一位可以是数字或字母X
    if not IDcard[:17].isdigit() or (IDcard[17] != 'X' and not IDcard[17].isdigit()):
        return "身份证格式不正确"

    # 身份证前6位是否是合理的行政编码
    address_number = IDcard[:6]
    if not is_valid_address_number_all(address_number):
        return "身份证前六位行政编码不合理"

    # 身份证中间8位是否是合理的出生日期
    birthday_number = IDcard[6:14]
    if not is_valid_date(birthday_number):
        return "身份证出生日期不合理"

    #身份证号码校验
    weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
    check_codes = '10X98765432'
    total = sum(int(num) * weight for num, weight in zip(IDcard[:17], weights))
    check_digit = check_codes[total % 11]
    if check_digit != IDcard[-1]:
        return "身份证末位不通过"

    # if int(IDcard[-2]) %2 == 0:
    #     return "身份证信息合法,且为女性"
    # else:
    #     return "身份证信息合法,且为男性"
    return 1

#企业信用代码合法性校验
def is_valid_address_number(address_number):
    # 打开文件并读取所有行
    with open('logic_rule/data/行政编码包含已撤销.txt', 'r', encoding='utf-8') as file:
        valid_addresses = set(line.strip() for line in file)
    return address_number in valid_addresses
def is_validate_org_code(code):
    """
    验证连续9位的组织机构代码的合法性。
    """
    if len(code) != 9:
        return False

    dict_char_to_value = {char: idx for idx, char in enumerate('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ')}

    if any(char not in dict_char_to_value for char in code):
        return False

    weights = [3, 7, 9, 10, 5, 8, 4, 2]
    base = code[:8]
    check_digit = code[-1]

    sum_value = sum(dict_char_to_value[base[i]] * weights[i] for i in range(8))
    mod_value = sum_value % 11

    computed_check_digit = (11 - mod_value) % 11
    computed_check_digit = 'X' if computed_check_digit == 10 else str(computed_check_digit)

    return check_digit == computed_check_digit
def is_valid_credit_code(credit_code):

    # 企业信用代码统一由18位阿拉伯数字或大写英文字母（I,O,Z,S,V）组成
    # 第1位为登记管理部门代码
    # 第2位为机构类别代码；
    # 第3-8位为登记管理机关行政区划码；    GB/T 2260-2007
    # 第9-17位为组织机构代码；           GB-11714
    # 第18为校验码。                   GB32100-2015

    if len(credit_code) != 18:
        return "企业信用代码长度不符"

    if not re.match(r'^[0-9A-Z]{18}$', credit_code):
        return "企业信用代码格式错误"

    #第1位校验
    valid_first_characters = set("123456789ABCDEFGY")
    if credit_code[0] not in valid_first_characters:
        return "登记管理部门代码错误"

    # 第2位校验
    valid_second_characters = set("1239")
    if credit_code[1] not in valid_second_characters:
        return "机构类别代码错误"

    # 第3-8位校验
    if not is_valid_address_number(credit_code[2:8]):
        return "登记管理机关行政区划码错误"

    # 第9-17位校验
    if not is_validate_org_code(credit_code[8:17]):
        return "组织机构代码错误"

    #第18位校验
    weights = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28]
    check_codes = '0123456789ABCDEFGHJKLMNPQRTUWXY'

    total = sum(check_codes.index(credit_code[i]) * weights[i] for i in range(17))
    check_digit = 31 - total % 31
    check_digit = check_codes[check_digit % 31]

    if check_digit != credit_code[-1]:
        return "企业信用代码校验错误"
    return 1

def generate_return_json(correct="", end=0, exception="", label=0, label_type=0,
                         offset=None, opt="", ppl="", pre_insert=1,
                         source="", start=0, tag="", text="", type="",
                         url="", word="", desc="", explain="",paragraph_index=""):
    return_json = {
        "correct": correct,
        "end": end,
        "exception": exception,
        "label": label,
        "label_type": label_type,
        "offset": offset,
        "opt": opt,
        "ppl": ppl,
        "pre_insert": pre_insert,
        "source": source,
        "start": start,
        "tag": tag,
        "text": text,
        "type": type,
        "url": url,
        "word": word,
        "desc": desc,
        "explain": explain,
        "paragraph_index": paragraph_index,
    }
    return return_json

def birthday_and_creditcode_check(extraction_result,info):

    check_result = []
    for individual in extraction_result[info]:
        if "公司名称" not in individual.keys():
            if individual['出生年月日']:
                if individual['出生年月日']['match'] and individual['姓名']['match']:
                    birthday_check_info = is_valid_birthday(individual['出生年月日']['match'])
                    if birthday_check_info!=1:
                        message = "【"+individual['角色']['match'] +"】"+ individual['姓名']['match'] + ": " + birthday_check_info
                        check_result.append(generate_return_json(offset=individual['出生年月日']['end_pos']-individual['出生年月日']['start_pos']+1,
                                                             start=individual['出生年月日']['start_pos'],
                                                             end=individual['出生年月日']['end_pos'], type=message))
            # else:
            #     birthday_check_info = "出生年月日信息缺失"
            #     message = individual['角色']['match'] + individual['姓名']['match'] + ": " + birthday_check_info
            #     check_result.append(generate_return_json(explain=message))

            if individual['身份证号']:
                if individual['身份证号']['match'] and individual['姓名']['match']:
                    IDcard_check_info = is_valid_IDcard(individual['身份证号']['match'])
                    if IDcard_check_info != 1:
                        message = "【"+individual['角色']['match'] +"】" + individual['姓名']['match'] + ": " + IDcard_check_info
                        check_result.append(generate_return_json(offset=individual['身份证号']['end_pos']-individual['身份证号']['start_pos']+1,
                                                                 start=individual['身份证号']['start_pos'],
                                                                 end=individual['身份证号']['end_pos'], type=message))
            # else:
            #     IDcard_check_info = "身份证号信息缺失"
            #     message =individual['角色']['match'] + individual['姓名']['match'] + ": " + IDcard_check_info
            #     check_result.append(generate_return_json(explain=message))
        else:
            if individual['企业信用代码']:
                if individual['企业信用代码']['match'] and individual['公司名称']['match']:
                    credit_code_check_info = is_valid_credit_code(individual['企业信用代码']['match'])
                    if credit_code_check_info!=1:
                        message = "【"+individual['角色']['match'] +"】" + individual['公司名称']['match'] + ": " + credit_code_check_info
                        check_result.append(generate_return_json(offset=individual['企业信用代码']['end_pos']-individual['企业信用代码']['start_pos']+1,
                                                                 start=individual['企业信用代码']['start_pos'],
                                                                 end=individual['企业信用代码']['end_pos'], type=message))
            # else:
            #     credit_code_check_info = "企业信用代码缺失"
            #     message = individual['角色']['match'] + individual['公司名称']['match'] + ": " + credit_code_check_info
            #     check_result.append(generate_return_json(explain=message))

    return check_result


def tjs_rule_check(extraction_result):
    check_result = []
    if len(extraction_result["原告信息"]) !=0:
        check_result.extend(birthday_and_creditcode_check(extraction_result,"原告信息"))
    if len(extraction_result["被告信息"]) !=0:
        check_result.extend(birthday_and_creditcode_check(extraction_result,"被告信息"))
    if len(extraction_result["第三人"]) !=0:
        check_result.extend(birthday_and_creditcode_check(extraction_result,"第三人"))
    if len(extraction_result["上诉人"]) !=0:
        check_result.extend(birthday_and_creditcode_check(extraction_result,"上诉人"))
    if len(extraction_result["被上诉人"]) !=0:
        check_result.extend(birthday_and_creditcode_check(extraction_result,"被上诉人"))
    for individual in extraction_result['本人']:
            if individual['身份证号'] and individual['姓名']['match']:
                IDcard_check_info = is_valid_IDcard(individual['身份证号']['match'])
                message = individual['姓名']['match'] + ": " + IDcard_check_info
                check_result.append(generate_return_json(offset=individual['身份证号']['end_pos']-individual['身份证号']['start_pos']+1,
                                                         start=individual['身份证号']['start_pos'],
                                                         end=individual['身份证号']['end_pos'], type=message))
            else:
                IDcard_check_info = "身份证号信息缺失"
                message = individual['姓名']['match'] + ": " + IDcard_check_info
                check_result.append(generate_return_json(type=message))

    return check_result


# result=get_extraction_results('../enetity_extraction/0715_base_test_data/67-135286097.txt')
# strr="黔西南布依族苗族自治州中级人民法院\n民事案（20178）黔23民初47号\n原告：组织机构代码：31422731 - 2"
# inputlist=strr.split('\n')
# result=extract_information(inputlist)
# result2=tjs_rule_check(result)
# correct_data=[]
# error_data=[]

# a,b=get_docx_extraction_result()
# result=tjs_rule_check(b)
# pass

# extract_result=get_docx_extraction_result()
# test_result=tjs_rule_check(extract_result)
#
#
# test_data=get_data()
# for i in range(24):
#     correct_extract_result=extract_information([test_data[44]['正确句子']])
#     error_extract_result=extract_information([test_data[i]['错误用例']])
#     correct_data.extend(tjs_rule_check(correct_extract_result))
#     error_data.extend(tjs_rule_check(error_extract_result))
# pass